package com.exchange.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author 李书文
 * @description 时间工具类
 * @time 2016年8月13日
 */
public class TimeUtil {
    public static List<Map<String, Object>> list;
    private final static ThreadLocal<SimpleDateFormat> timeFormater = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        }
    };
    private final static ThreadLocal<SimpleDateFormat> dateFormater = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd");
        }
    };

    /**
     * 格式化日期(精确到秒)
     *
     * @return
     */
    public static String getNow() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.format(System.currentTimeMillis());
    }

    /**
     * 格式化日期(精确到秒)
     *
     * @return
     */
    public static String getTIME() {
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
        return format.format(System.currentTimeMillis());
    }

    /**
     * 格式化日期(精确到天)
     *
     * @return
     */
    public static String getDay() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        return format.format(System.currentTimeMillis());
    }

    public static String getDayFormat() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy年-MM月-dd日");
        return format.format(System.currentTimeMillis());
    }

    //获取时分
    public static String getHour() {
        SimpleDateFormat format = new SimpleDateFormat("HH:mm");
        return format.format(System.currentTimeMillis());
    }

    public static List<Map<String, Object>> printWeekdays() {
        list = new ArrayList<Map<String, Object>>();
        Calendar calendar = Calendar.getInstance();
        for (int i = 0; i < 7; i++) {
            printDay(calendar);
            calendar.add(Calendar.DATE, 1);
        }
        return list;
    }

    private static String printDay(Calendar calendar) {
        SimpleDateFormat dateFormat1 = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat dateFormat2 = new SimpleDateFormat("MM");
        SimpleDateFormat dateFormat3 = new SimpleDateFormat("dd");
        SimpleDateFormat dateFormat4 = new SimpleDateFormat("EE");
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("year", dateFormat1.format(calendar.getTime()));
        map.put("month", dateFormat2.format(calendar.getTime()).replaceAll("^(0+)", "") + "月");
        map.put("day", dateFormat3.format(calendar.getTime()));
        map.put("week", dateFormat4.format(calendar.getTime()).replaceAll("^(星期+)", ""));
        list.add(map);
        return null;
    }

    /**
     * 将日期格式转换成yyyy-MM-dd的字符串格式 返回值如：2016-8-13
     *
     * @param time 要转换的日期
     * @return
     */
    public static String dateToString(Date time) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); // 定义将日期格式要换成的格式
        String stringTime = formatter.format(time);
        return stringTime;
    }


    /**
     * 将字符串转为日期类型
     *
     * @param date
     * @return
     */
    public static Date toDate(String date) {
        return toDate(date, timeFormater.get());
    }

    public static Date toDate(String date, SimpleDateFormat dateFormater) {
        try {
            return dateFormater.parse(date);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 获取时间差
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param format    时间格式 例如:yyyy-MM-dd HH:mm:ss
     * @param str       计算 d:计算天数，h:计算小时，m:计算分钟
     * @return
     */
    public static Long dateDiff(String startTime, String endTime, String format, String str) {
        // 按照传入的格式生成一个simpledateformate对象
        SimpleDateFormat sd = new SimpleDateFormat(format);
        long nd = 1000 * 24 * 60 * 60;// 一天的毫秒数
        long nh = 1000 * 60 * 60;// 一小时的毫秒数
        long nm = 1000 * 60;// 一分钟的毫秒数
        long ns = 1000;// 一秒钟的毫秒数
        long diff;
        long day = 0;
        long hour = 0;
        long min = 0;
        long sec = 0;
        // 获得两个时间的毫秒时间差异
        try {
            diff = sd.parse(endTime).getTime() - sd.parse(startTime).getTime();
            day = diff / nd;// 计算差多少天
            hour = diff % nd / nh + day * 24;// 计算差多少小时
            min = diff % nd % nh / nm + day * 24 * 60;// 计算差多少分钟
            sec = diff % nd % nh % nm / ns;// 计算差多少秒
            // 输出结果
            System.out.println(
                    "时间相差：" + day + "天" + (hour - day * 24) + "小时" + (min - day * 24 * 60) + "分钟" + sec + "秒。");
            System.out.println("hour=" + hour + ",min=" + min);
            if (str.equalsIgnoreCase("d")) {
                return day;
            } else if (str.equalsIgnoreCase("h")) {
                return hour;
            } else {
                return min;
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        if (str.equalsIgnoreCase("h")) {
            return hour;
        } else {
            return min;
        }
    }

    /**
     * 判断给定字符串时间是否为今日
     *
     * @param date
     * @return boolean
     */
    public static boolean isToday(String date) {
        boolean b = false;
        Date time = toDate(date);
        Date today = new Date();
        if (time != null) {
            String nowDate = dateFormater.get().format(today);
            String timeDate = dateFormater.get().format(time);
            if (nowDate.equals(timeDate)) {
                b = true;
            }
        }
        return b;
    }

    /**
     * 获取当前日期是星期几
     *
     * @param date
     * @return
     */
    public static int getWeekOfDate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0)
            w = 0;
        return w;
    }

    /**
     * 判断当前日期是否是本周
     *
     * @param date
     * @return
     */
    public static boolean isThisWeek(Date date) {
        Calendar calendar = Calendar.getInstance();
        int currentWeek = calendar.get(Calendar.WEEK_OF_YEAR);
        calendar.setTime(date);
        int paramWeek = calendar.get(Calendar.WEEK_OF_YEAR);
        if (paramWeek == currentWeek) {
            return true;
        }
        return false;
    }

    /**
     * 以友好的方式显示时间 如:xx分钟前，xx天前
     *
     * @param date
     * @return
     */
    public static String friendly_time(String date) {
        Date time = null;

        if (isInEasternEightZones())
            time = toDate(date);
        else
            time = transformTime(toDate(date), TimeZone.getTimeZone("GMT+08"), TimeZone.getDefault());

        if (time == null) {
            return "Unknown";
        }
        String ftime = "";
        Calendar cal = Calendar.getInstance();

        // 判断是否是同一天
        String curDate = dateFormater.get().format(cal.getTime());
        String paramDate = dateFormater.get().format(time);
        if (curDate.equals(paramDate)) {
            int hour = (int) ((cal.getTimeInMillis() - time.getTime()) / 3600000);
            if (hour == 0)
                ftime = Math.max((cal.getTimeInMillis() - time.getTime()) / 60000, 1) + "分钟前";
            else
                ftime = hour + "小时前";
            return ftime;
        }

        long lt = time.getTime() / 86400000;
        long ct = cal.getTimeInMillis() / 86400000;
        int days = (int) (ct - lt);
        if (days == 0) {
            int hour = (int) ((cal.getTimeInMillis() - time.getTime()) / 3600000);
            if (hour == 0)
                ftime = Math.max((cal.getTimeInMillis() - time.getTime()) / 60000, 1) + "分钟前";
            else
                ftime = hour + "小时前";
        } else if (days == 1) {
            ftime = "昨天";
        } else if (days == 2) {
            ftime = "前天 ";
        } else if (days > 2 && days < 31) {
            ftime = days + "天前";
        } else if (days >= 31 && days <= 2 * 31) {
            ftime = "一个月前";
        } else if (days > 2 * 31 && days <= 3 * 31) {
            ftime = "2个月前";
        } else if (days > 3 * 31 && days <= 4 * 31) {
            ftime = "3个月前";
        } else {
            ftime = dateFormater.get().format(time);
        }
        return ftime;
    }

    /**
     * 判断用户的设备时区是否为东八区（中国） 2016年8月15日
     *
     * @return
     */
    public static boolean isInEasternEightZones() {
        boolean defaultVaule = true;
        if (TimeZone.getDefault() == TimeZone.getTimeZone("GMT+08"))
            defaultVaule = true;
        else
            defaultVaule = false;
        return defaultVaule;
    }

    /**
     * 根据不同时区，转换时间 2016年8月15日
     *
     * @return
     */
    public static Date transformTime(Date date, TimeZone oldZone, TimeZone newZone) {
        Date finalDate = null;
        if (date != null) {
            int timeOffset = oldZone.getOffset(date.getTime()) - newZone.getOffset(date.getTime());
            finalDate = new Date(date.getTime() - timeOffset);
        }
        return finalDate;
    }

    /**
     * 判断是否是过去的日期
     *
     * @param str 输入的日期
     * @return true 早于现在，false 晚于现在
     */
    public static boolean isLaterThanNow(String str) {

        boolean flag = false;
        Date nowDate = new Date();
        Date pastDate = null;
        //格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm", Locale.CHINA);
        //在日期字符串非空时执行
        try {
            //将字符串转为日期格式，如果此处字符串为非合法日期就会抛出异常。
            pastDate = sdf.parse(str);
            //调用Date里面的before方法来做判断
            flag = pastDate.before(nowDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return flag;
    }
}
